import { RepoLink, Link } from '@brillout/docpress'
import { UiFrameworkExtension } from '../../components'

The usual recommendation is:
 - For fetching a page's initial data, use Vike's `+data` hook. See <Link href="#page-data-with-data" />.
 - For data mutations and subsequent data (e.g. pagination), use a tool like tRPC or TanStack Query. See <Link href="#data-mutation-subsequent-data" />.


## Page data with `+data`

You can fetch the initial data of a page by using <Link href="/data">Vike's `+data` hook</Link>, then access it by using the <Link href="/useData">component hook `useData()`</Link>.

```ts
// /pages/movies/@id/+data.ts
// Environment: server

export { data }
export type Data = Awaited<ReturnType<typeof data>>

import fetch from 'node-fetch'
import type { PageContextServer } from 'vike/types'

async function data(pageContext: PageContextServer) {
  const { id } = pageContext.routeParams
  const response = await fetch(`https://star-wars.brillout.com/api/films/${id}.json`)

  let movie = await response.json()
  // `movie` is serialized and passed to the client. Therefore, we pick only the
  // data the client needs in order to minimize what is sent over the network.
  movie = { title: movie.title, release_date: movie.release_date }

  // data() runs only on the server-side by default, we can therefore use ORM/SQL queries.
  /* With an ORM:
  const movies = await Movie.findAll({ select: ['title', 'release_date'] }) */
  /* With SQL:
  const movies = await sql.run('SELECT { title, release_date } FROM movies;') */

  return {
    movie
  }
}
```

> `pageContext` holds contextual information, see <Link href="/pageContext" />.

> The `@id` in the file path `/pages/movie/@id/+data.js` denotes a route parameter which value is available at <Link href="/pageContext#routeParams">`pageContext.routeParams.id`</Link>, see <Link href="/routing" />.

```ts
// pages/movies/@id/SomeComponent.ts
// Environment: server, client

import { useData } from 'vike-react/useData'
/* Or:
import { useData } from 'vike-vue/useData'
import { useData } from 'vike-solid/useData'
*/
import type { Data } from './+data'

/* ... */

// Inside any UI component
const data = useData<Data>()
const { title, release_date } = data
```

> `useData()` is provided by <UiFrameworkExtension name />. If you don't use such extension then see <Link href="/useData#without-vike-react-vue-solid" doNotInferSectionTitle />.

The `+data` hook can only be used for fetching the initial data of the page. For other use cases, see <Link href="#data-mutation-subsequent-data" />.


## Page data with tools

Some data-fetching tools have Vike extensions that enable your components to fetch initial data:
 - [`vike-react-query`](https://github.com/vikejs/vike-react/tree/main/packages/vike-react-query#readme) - [TanStack Query](https://tanstack.com/query) integration for <Link href="/vike-react">`vike-react`</Link>
 - [`vike-vue-query`](https://github.com/vikejs/vike-vue/tree/main/packages/vike-vue-query#readme) - [TanStack Query](https://tanstack.com/query) integration for <Link href="/vike-vue">`vike-vue`</Link>
 - [`vike-solid-query`](https://github.com/vikejs/vike-solid/tree/main/packages/vike-solid-query#readme) - [TanStack Query](https://tanstack.com/query) integration for <Link href="/vike-solid">`vike-solid`</Link>
 - 🚧 `vike-react-telefunc` - [Telefunc](https://telefunc.com/) integration for <Link href="/vike-react">`vike-react`</Link>

> With these tools, instead of using Vike's `+data` hook, you can directly fetch data in components, including your <Link href="/Layout">`<Layout>` components</Link>.


## Data mutation & subsequent data

For data mutation and subsequent data fetching (such as pagination data), use a data tool.

### RPC

We generally recommend using RPC. It's simple, flexible, and performant.

For a list of RPC tools, see <Link href="/RPC" />.

### API routes

A common alternative to RPC is to use API routes, see <Link href="/api-routes" />.

### GraphQL

For large teams, it may make sense to use GraphQL instead of RPC.

With Vike, you can manually integrate GraphQL tools yourself, giving you complete control over integration:

- <Link href="/apollo-graphql" />
- <Link href="/relay" />
- <Link href="/urql" />

> In addition to manual integration, [you will soon](https://github.com/vikejs/vike/issues/1715) have the option to use <Link href="/extensions">Vike extensions</Link> for automatic integration.


## Pre-rendering (SSG)

For <Link href="/pre-rendering">pre-rendered pages / SSG apps</Link>, in order to fetch dynamic data from an external server, make sure to load and execute `data()` only on the client-side, see <Link href="/data#environment" />.


## Global data

A common use case is fetching and/or initializing global data, for example:
- <Link href="/auth">Authentication information about the logged-in user</Link>
- <Link href="/i18n">Data for i18n</Link>

You can store the data in the <Link href="/globalContext">`globalContext` object</Link> or the <Link href="/pageContext">`pageContext` object</Link>, while fetching/initializing the data using <Link href="/onCreateGlobalContext">`+onCreateGlobalContext()`</Link>/<Link href="/onCreatePageContext">`+onCreatePageContext()`</Link>. You can use <Link href="/passToClient">`+passToClient`</Link> if you want to use the data on the client-side.


## State management

See <Link href="/store" />.



## See also

- <Link href="/data" />
- <Link href="/useData" />
- <Link href="/RPC" />
- <Link href="/api-routes" />
